/**
  ******************************************************************************
  * @file    dbus.c
	* @author  jingqiao
  * @brief   recevice and decode dbus.
  ******************************************************************************
  * @attention
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "dbus.h"
#include "usart.h"
#include "dma.h"
#ifdef DBUS_IWDG
#include "iwdg.h"
#endif

uint8_t dbus_buffer[DBUS_BUFFER_SIZE] = {};
dbus_struct dbus_ctrl_data = {};

DMA_HandleTypeDef* dbus_hdma_usart_rx_ptr;
UART_HandleTypeDef* dbus_huart_ptr;

void dbus_init(UART_HandleTypeDef* huart_ptr, DMA_HandleTypeDef* hdma_usart_rx_ptr)
{
	dbus_hdma_usart_rx_ptr = hdma_usart_rx_ptr;
	dbus_huart_ptr = huart_ptr;
	__HAL_UART_ENABLE_IT(dbus_huart_ptr, UART_IT_RXNE);
	__HAL_UART_ENABLE_IT(dbus_huart_ptr, UART_IT_IDLE);
	HAL_UART_Receive_DMA(dbus_huart_ptr, dbus_buffer, DBUS_BUFFER_SIZE);
	dbus_ctrl_data.channel.CH[0] = 0x400;
	dbus_ctrl_data.channel.CH[1] = 0x400;
	dbus_ctrl_data.channel.CH[2] = 0x400;
	dbus_ctrl_data.channel.CH[3] = 0x400;
	dbus_ctrl_data.channel.rolling_wheel = 0x400;
}

void dbus_decode()
{
	dbus_ctrl_data.channel.CH[0] = dbus_buffer[0] | ((dbus_buffer[1] & 0b00000111) << 8);//[0]all, [1]high 3
	dbus_ctrl_data.channel.CH[1] = ((dbus_buffer[1] & 0b11111000) >> 3) | ((dbus_buffer[2] & 0b00111111) << 5);//[1]low 5, [2]high 6
	dbus_ctrl_data.channel.CH[2] = ((dbus_buffer[2] & 0b11000000) >> 6) | ((dbus_buffer[3] & 0b11111111) << 2) | ((dbus_buffer[4] & 0xb00000001) << 10);//[2]low 2, [3]all, [4]high 1
	dbus_ctrl_data.channel.CH[3] = ((dbus_buffer[4] & 0b11111110) >> 1) | ((dbus_buffer[5] & 0b00001111) << 7);//[4]low 7, [5]high 4
	dbus_ctrl_data.channel.s1 = ((dbus_buffer[5] & 0b11000000) >> 6);
	dbus_ctrl_data.channel.s2 = ((dbus_buffer[5] & 0b00110000) >> 4);
	dbus_ctrl_data.mouse.x = dbus_buffer[6] | (dbus_buffer[7] << 8);
	dbus_ctrl_data.mouse.y = dbus_buffer[8] | (dbus_buffer[9] << 8);
	dbus_ctrl_data.mouse.z = dbus_buffer[10] | (dbus_buffer[11] << 8);
	dbus_ctrl_data.mouse.left_key = dbus_buffer[12];
	dbus_ctrl_data.mouse.right_key = dbus_buffer[13];
	dbus_ctrl_data.keyboard.w = dbus_buffer[14] & 0b00000001;
	dbus_ctrl_data.keyboard.s = (dbus_buffer[14] & 0b00000010) >> 1;
	dbus_ctrl_data.keyboard.a = (dbus_buffer[14] & 0b00000100) >> 2;
	dbus_ctrl_data.keyboard.d = (dbus_buffer[14] & 0b00001000) >> 3;
	dbus_ctrl_data.keyboard.q = (dbus_buffer[14] & 0b00010000) >> 4;
	dbus_ctrl_data.keyboard.e = (dbus_buffer[14] & 0b00100000) >> 5;
	dbus_ctrl_data.keyboard.shift = (dbus_buffer[14] & 0b01000000) >> 6;
	dbus_ctrl_data.keyboard.ctrl = (dbus_buffer[14] & 0b10000000) >> 7;
	dbus_ctrl_data.channel.rolling_wheel = (dbus_buffer[17] << 8) | dbus_buffer[16];
}

void dbus_callback()
{
	if (__HAL_UART_GET_FLAG(dbus_huart_ptr, UART_FLAG_IDLE) != RESET)
	{
#ifdef DBUS_IWDG
		HAL_IWDG_Refresh(&hiwdg);
#endif
		__HAL_UART_CLEAR_IDLEFLAG(dbus_huart_ptr);
		HAL_UART_DMAStop(dbus_huart_ptr);
		if (__HAL_DMA_GET_COUNTER(dbus_hdma_usart_rx_ptr) == 0)
			dbus_decode();
		HAL_UART_Receive_DMA(dbus_huart_ptr, dbus_buffer, DBUS_BUFFER_SIZE);
	}
}
